/**
 * 
 */
package com.xxl.job.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.util.ObjectUtils;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import com.xxl.job.core.biz.impl.ExecutorBizImpl;
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;

@Configuration
@ConditionalOnProperty(prefix = XxlJobAdminProperties.JOB_PREFIX, name = "enable", havingValue = "true", matchIfMissing = true)
@EnableConfigurationProperties({ XxlJobAdminProperties.class, XxlJobExecutorProperties.class })
@ComponentScan(basePackages = { "com.xxl.job.core.controller" })
public class XxlJobAutoConfiguration implements EnvironmentAware, ApplicationContextAware {
	private final static Logger log = LoggerFactory.getLogger(XxlJobAutoConfiguration.class);
	private Environment environment;
	private static ApplicationContext applicationContext;

	/**
	 * @return the {@link #applicationContext}
	 */
	public static ApplicationContext getApplicationContext() {
		return applicationContext;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.springframework.context.EnvironmentAware#setEnvironment(org.
	 * springframework.core.env.Environment)
	 */
	@Override
	public void setEnvironment(Environment environment) {
		this.environment = environment;
	}

	@Bean
	@ConditionalOnMissingBean(ExecutorBizImpl.class)
	@ConditionalOnProperty(prefix = XxlJobAdminProperties.JOB_PREFIX, name = "enable", havingValue = "true", matchIfMissing = true)
	public ExecutorBizImpl executorBizImpl() {
		return new ExecutorBizImpl();
	}

	@Bean(name = "xxlJobTokenInterceptConfig")
	@ConditionalOnProperty(prefix = XxlJobAdminProperties.JOB_PREFIX, name = "enable", havingValue = "true", matchIfMissing = true)
	public WebMvcConfigurer xxlJobTokenInterceptConfig() {
		return new WebMvcConfigurer() {
			@Override
			public void addInterceptors(InterceptorRegistry registry) {
				// 注册拦截器
				log.info("[xxl-job] Initializing XxlJobTokenHandlerInterceptor");
				registry.addInterceptor(new XxlJobTokenHandlerInterceptor()).addPathPatterns("/api/xxl-job/**");
			}
		};
	}

	@Bean
	@ConditionalOnMissingBean(XxlJobSpringExecutor.class)
	@ConditionalOnProperty(prefix = XxlJobAdminProperties.JOB_PREFIX, name = "enable", havingValue = "true", matchIfMissing = true)
	public XxlJobSpringExecutor xxlJobExecutor(@Autowired XxlJobAdminProperties adminProperties,
			@Autowired XxlJobExecutorProperties executorProperties) {
		if (ObjectUtils.isEmpty(executorProperties.getAppname())) {
			String appName = environment.getProperty("spring.application.name");
			executorProperties.setAppname(appName);
		}
		log.info("[xxl-job] AutoConfiguration： adminAddress = {} ", adminProperties.getAddresses());
		log.info("[xxl-job] AutoConfiguration： executor = {}", executorProperties);
		XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
		xxlJobSpringExecutor.setAdminAddresses(adminProperties.getAddresses());
		xxlJobSpringExecutor.setAccessToken(adminProperties.getAccessToken());
		xxlJobSpringExecutor.setAppname(executorProperties.getAppname());
		xxlJobSpringExecutor.setAddress(executorProperties.getAddress());
		xxlJobSpringExecutor.setLogPath(executorProperties.getLogPath());
		xxlJobSpringExecutor.setIp(executorProperties.getIp());
		xxlJobSpringExecutor.setPort(executorProperties.getPort());
		xxlJobSpringExecutor.setLogRetentionDays(executorProperties.getLogRetentionDays());
		xxlJobSpringExecutor.setLogMaxFileSize(executorProperties.getLogMaxFileSize());
		return xxlJobSpringExecutor;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.springframework.context.ApplicationContextAware#setApplicationContext
	 * (org.springframework.context.ApplicationContext)
	 */
	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		XxlJobAutoConfiguration.applicationContext = applicationContext;
	}
}
